package com.stylefeng.guns.modular.VpnUserAnalyze.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.stylefeng.guns.core.common.constant.DatasourceEnum;
import com.stylefeng.guns.core.mutidatasource.annotion.DataSource;
import com.stylefeng.guns.modular.system.model.VpnUserAnalyze;
import com.stylefeng.guns.modular.system.dao.VpnUserAnalyzeMapper;
import com.stylefeng.guns.modular.VpnUserAnalyze.service.IVpnUserAnalyzeService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.vpn.bo.*;
import com.stylefeng.guns.modular.vpn.entity.*;
import com.stylefeng.guns.modular.vpn.utils.*;
import com.stylefeng.guns.modular.vpn.vo.ConnectServerVO;
import com.stylefeng.guns.modular.vpn.vo.PlatformVO;
import com.stylefeng.guns.modular.vpn.vo.UserIPVO;
import com.stylefeng.guns.modular.vpn.vo.VersionVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author stylefeng
 * @since 2020-04-13
 */
@Service
@Slf4j
public class VpnUserAnalyzeServiceImpl extends ServiceImpl<VpnUserAnalyzeMapper, VpnUserAnalyze> implements IVpnUserAnalyzeService {

    @Autowired
    private VpnUserAnalyzeMapper analyzeMapper;

    @Value("${geo-ip-database-path}")
    private String databasePath;

    @Override
    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    public UserIPVO getRegisterUserIPLocations() {
        //得到注册用户IP列表
        List<UserIPBO> userIPList = analyzeMapper.queryUserIPList();

        List<UserIPBO> payUserIPLit = analyzeMapper.queryPayUserIPList();

        UserIPVO  userIPVO = new UserIPVO();

        Ip2Region  ip2Region = new Ip2Region(databasePath);

        //<省份名称，数量>
        Map<String,Integer> cityMap = new HashMap<>();
        //付费用户的所在 <省份，数量>
        Map<String,Integer> payCityMap = new HashMap<>();

        userIPList.forEach(userIPBO -> {
            if (StringUtils.isNotEmpty(userIPBO.getIpAddr())){
                IPInfo info =
                        ip2Region.getIPInfo(userIPBO.getIpAddr());
                cityMap.merge(Ip2Region.getFinalCityName(info), userIPBO.getIpCount(), Integer::sum);
            }
        });

        //根据城市对应的注册用户数量，重新排序城市名称
        Map<String,Integer> sortMap = MapSortUtil.sortByValueDesc(cityMap);

        int regionMinCount = 50;//地区用户数量最少值，小于这个数值不展示
        int top = 30;

        //收集城市名称Top列表
        List<String> nameList = new ArrayList<>();
        //收集城市名称对应数量的Top列表
        List<Integer> countList = new ArrayList<>();

        if(sortMap != null){
            AtomicInteger index = new AtomicInteger();
            //遍历省份集合,（省份，用户注册数量）
            sortMap.forEach((provinceName,regCount)->{
                index.getAndIncrement();
                if (index.get() > top){
                    return;
                }
                nameList.add(provinceName);
                countList.add(regCount);
//                if(regCount >= regionMinCount){
//                    nameList.add(provinceName);
//                    countList.add(regCount);
//                }
            });
        }

        int regionTopSize = nameList.size();
        //地区的城市Top名称数组
        String[] regionNamesBO = new String[regionTopSize];
        //地区城市对应的Top数量数组
        Integer[] regionCountsBO = new Integer[regionTopSize];

        regionNamesBO = nameList.toArray(regionNamesBO);

        payUserIPLit.forEach(u -> {
            if (StringUtils.isNotEmpty(u.getIpAddr())){
                IPInfo info =
                        ip2Region.getIPInfo(u.getIpAddr());
                payCityMap.merge(Ip2Region.getFinalCityName(info), u.getIpCount(), Integer::sum);
            }
        });

        Integer[] payRegionCounts = new Integer[regionTopSize];
        for (int i = 0; i < regionTopSize; i++) {
            if (payCityMap.get(regionNamesBO[i]) != null){
                payRegionCounts[i] = payCityMap.get(regionNamesBO[i]);
            }else{
                payRegionCounts[i] = 0;
            }
        }

        userIPVO.setRegionNames(regionNamesBO);
        userIPVO.setRegionCounts(countList.toArray(regionCountsBO));
        userIPVO.setPayRegionCounts(payRegionCounts);

        return userIPVO;
    }

    /**
     * 查询版本分布情况
     * @return
     */
    @Override
    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    public VersionVO getVersionDistribution() {
        VersionVO versionVO = new VersionVO();
        List<VersionBO> versionBOList = analyzeMapper.queryVersionDistribution();
        //平台，版本，数量
        Map<String,Map<String,Integer>> platformAndVersionMap = new HashMap<>();
        List<String> platformNameList = new ArrayList<>();
        List<String> versionNameList = new ArrayList<>();

        if (versionBOList != null && versionBOList.size() > 0){
            versionBOList.forEach(versionBO -> {

                Map<String,Integer> versionMap =
                        platformAndVersionMap.get(PlatformUtil.getPlatformName(versionBO.getPlatform()));
                if(versionMap == null){
                    versionMap = new HashMap<>();
                }
                versionMap.put(versionBO.getVersionName(),versionBO.getVersionCount().intValue());
                platformAndVersionMap.put(PlatformUtil.getPlatformName(versionBO.getPlatform()),versionMap);

                //记录平台名称,去重
                if(!platformNameList.contains(PlatformUtil.getPlatformName(versionBO.getPlatform()))){
                    platformNameList.add(PlatformUtil.getPlatformName(versionBO.getPlatform()));
                }

                //记录版本名称，去重
                if (!versionNameList.contains(versionBO.getVersionName())){
                    versionNameList.add(versionBO.getVersionName());
                }
            });

            Map<String,Integer[]> versionCountMap = new HashMap<>();


            //平台：（版本号，数量）
            platformAndVersionMap.forEach((k,v)->{
                //版本号，数量
                v.forEach((versionName,count)->{
                    Integer[] countArray =  versionCountMap.get(versionName);
                    if (countArray == null){
                        countArray = new Integer[platformNameList.size()];
                    }
                    countArray[platformNameList.indexOf(k)] = count;
                    //存储版本号对应的平台数量数组
                    versionCountMap.put(versionName,countArray);
                });
            });

            //产出-> 版本号，count[p1,p2,p3,p4]
            List<VersionCounts> versionCountsList = new ArrayList<>();
            versionCountMap.forEach((k,v)->{
                versionCountsList.add(VersionCounts.builder()
                                            .versionName(k)
                                            .counts(v)
                                            .build());
            });

            String[] platformNames = new String[platformNameList.size()];
            String[] versionNames = new String[versionNameList.size()];

            versionVO.setPlatformNames(platformNameList.toArray(platformNames));
            versionVO.setVersionNames(versionNameList.toArray(versionNames));
            versionVO.setVersionCounts(versionCountsList);
        }

        return versionVO;
    }

    @Override
    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    public PlatformVO getPlatformCount() {
        List<PlatformBO> platformBOS =  analyzeMapper.queryPlatformCount();
        String[] axis = {};
        Integer[] series = {};
        if (platformBOS != null && platformBOS.size() > 0){
            int len = platformBOS.size();
            axis = new String[len];
            series = new Integer[len];

            Map<String,Integer> maps = new HashMap<>();

            for (int i = 0; i < len; i++) {
                PlatformBO p = platformBOS.get(i);
                String str = PlatformUtil.getPlatformName(p.getPlatform());
                maps.put(str,p.getPlatformCount());
            }
            Map<String,Integer> sorted = MapSortUtil.sortByValueDesc(maps);
            if(sorted != null){
                List<String> sList = new ArrayList<>();
                List<Integer> iList = new ArrayList<>();
                sorted.forEach((k,v)->{
                    sList.add(k);
                    iList.add(v);
                });
                sList.toArray(axis);
                iList.toArray(series);
            }
        }
        return PlatformVO.builder().yAxis(axis).seriesData(series).build();
    }

    @Override
    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    public ConnectServerVO getConnectServerInfo() {
        List<ServerIntervalOnlineBO> serverOnlineBOList = analyzeMapper.queryConnectServer();
        //时段集合
        List<String> hourTimes = new ArrayList<>();
        //节点名称集合
        List<String> serverNames  = new ArrayList<>();

        //节点名称，（时段，数量）
        Map<String,Map<String,Integer>> nameAndCountMap = new HashMap<>();

        String hour = TimeUtil.dateToGTMString(new Date(),"HH");
        String minute = TimeUtil.dateToGTMString(new Date(),"mm");
        int maxH = Integer.parseInt(hour);
        if (Integer.parseInt(minute) < 59){
            maxH = maxH -1;
        }

        for (int i = 0; i <= maxH; i++){
            if(i < 10){
                hourTimes.add("0"+i);
            }else{
                hourTimes.add(""+i);
            }
        }

        serverOnlineBOList.forEach(s->{
            if (StringUtils.isNotEmpty(s.getJsonData())){
                try {
                    JSONArray jsonArray = JSONArray.parseArray(s.getJsonData());
                    if (jsonArray != null){
                        int len = jsonArray.size();
                        for (int i = 0; i < len; i++) {
                            JSONObject jsonObject = jsonArray.getJSONObject(i);
                            //判断集合中是否已存在节点名称
                            if(!serverNames.contains(jsonObject.getString("serverName"))){
                                serverNames.add(jsonObject.getString("serverName"));
                            }

                            //筛选每个节点对应的时段和数量
                            Map<String,Integer>  countMap =
                                    nameAndCountMap.get(jsonObject.getString("serverName"));
                            if (countMap == null){
                                countMap = new HashMap<>();
                            }
                            countMap.put(s.getConnectTime(),jsonObject.getInteger("serverCount"));
                            nameAndCountMap.put(jsonObject.getString("serverName"),countMap);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });


        //节点，时段数量数组
        Map<String,Integer[]> serverCountMap = new HashMap<>();

        nameAndCountMap.forEach((n,hc)->{
            Integer[] countArray = serverCountMap.get(n);
            if (countArray == null){
                countArray = new Integer[hourTimes.size()];
                int len = countArray.length;
                for (int i = 0; i < len; i++) {
                    countArray[i] = 0;
                }
            }
            Integer[] finalCountArray = countArray;
            hc.forEach((h, c)->{
                finalCountArray[hourTimes.indexOf(h)] = c;
            });
            serverCountMap.put(n,finalCountArray);
        });
        //节点数量对象列表
        List<ServerOnlineArray> serverArrayList  = new ArrayList<>();
        serverCountMap.forEach((k,v)->{
            serverArrayList.add(ServerOnlineArray.builder()
                                    .serverName(k).countArray(v)
                                    .build());
        });

        //时段(0~当前时间) 数组
        String[] hourTimeArray = new String[hourTimes.size()];
        hourTimes.toArray(hourTimeArray);
        //节点名称 数组
        String[] serverNameArray = new String[serverNames.size()];
        serverNames.toArray(serverNameArray);

        return ConnectServerVO.builder()
                .serverNameArray(serverNameArray)
                .hourArray(hourTimeArray)
                .serverCountArray(serverArrayList).build();
    }

    @Override
    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    public Object queryPayRatio() {
        return analyzeMapper.queryPayRatio();
    }
}
